//
//  DERRegisterViewController.swift
//  ezyform
//
//  Created by MoennigQ on 8/4/20.
//  Copyright © 2020 Client.Solution Pty Ltd. All rights reserved.
//

import UIKit
import WebKit
import SnapKit
import Alamofire
class DERRegisterViewController: BaseViewController {
    let withoutNetworkView = DatalLoadFaildView()
    
    var gwtID: String = ""
    var wkWebView : WKWebView!
    private var contentView: UIView?
    var progBar :UIProgressView!
    var homeURL: URL?
    var currentURL: URL?
    var currentMethod: String?
    override func viewDidLoad() {
        super.viewDidLoad()
        loadData()
        
    }
    func loadData(){
        self.view.backgroundColor = .white
        let linkStr = APPConfig.serverAddress + "derr/installation_details?token=" + APPConfig.loginInfo.access_token + "&gwtid=" + gwtID
        guard let url = URL(string: linkStr) else{
            return
        }
        self.homeURL = url
        self.currentURL = url
        self.currentMethod = "GET"
        let request = NSMutableURLRequest(url: url)
        request.setValue("iOS", forHTTPHeaderField: "X-API-MOBILE-TYPE")
        request.timeoutInterval = 10
        // 用户交互信息管理
        let userContent = WKUserContentController()
        
        let config = WKWebViewConfiguration()
        config.userContentController = userContent
        
        wkWebView = WKWebView(frame: CGRect(x: 0, y: 0, width: 0, height: 0), configuration: config)
        wkWebView.navigationDelegate = self
        wkWebView.uiDelegate = self
        self.view.addSubview(wkWebView)
        wkWebView.snp.makeConstraints { (make) in
            make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top)
            make.left.right.bottom.equalToSuperview()
        }
        withoutNetworkView.retryBtn.addTarget(self, action: #selector(retryBtnClick), for: UIControl.Event.touchUpInside)
        //
        withoutNetworkView.isHidden = true
        self.view.addSubview(withoutNetworkView)
        withoutNetworkView.snp.makeConstraints { (make) in
            make.edges.equalTo(self.wkWebView)
        }
        //process bar
        progBar = UIProgressView()
        progBar.progress = 0.0
        progBar.tintColor = UIColor(rgb: 0x3BADFF)
        progBar.backgroundColor = .white
        self.view.addSubview(progBar)
        progBar.snp.makeConstraints { (make) in
            make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top)
            make.left.right.equalToSuperview()
            make.height.equalTo(3)
        }
        if Connectivity.isConnectedToInternet {
            progBar.alpha = 1.0
            wkWebView.load(request as URLRequest)
        }else{
            self.showWithoutInternetBackView()
        }
        self.wkWebView.addObserver(self, forKeyPath: "title", options: NSKeyValueObservingOptions.new, context: nil)
        self.wkWebView.addObserver(self, forKeyPath: "estimatedProgress", options: NSKeyValueObservingOptions.new, context: nil)
        //监听所有URL的变化（包括AJAX请求），处理forget pwd中发送邮件后，点击login直接返回到iOS的Login界面
        self.wkWebView.addObserver(self, forKeyPath: "URL", options: NSKeyValueObservingOptions.new, context: nil)
    }
    @objc func doneBtnClick(_ sender: UIBarButtonItem){
        view.endEditing(true)
    }
    func addDERPortalLinkBtn(){
        let btn = UIBarButtonItem(image: UIImage(named: "der_register_link"), style: UIBarButtonItem.Style.plain, target: self, action: #selector(toDerRegisterPortal))
        self.navigationItem.rightBarButtonItem = btn
    }
    //没有网络
    func showWithoutInternetBackView(){
        self.title = ""
        self.withoutNetworkView.isHidden = false
        self.wkWebView.isHidden = true
        self.addDERPortalLinkBtn()
    }
    //
    func showWebView(){
        self.withoutNetworkView.isHidden = true
        self.wkWebView.isHidden = false
        if let url = self.currentURL, url.absoluteString.contains("installation_details"){
            self.addDERPortalLinkBtn()
        }else{
            self.navigationItem.rightBarButtonItem = nil
        }
    }
    @objc func retryBtnClick(){
        if let url = self.currentURL, let method = self.currentMethod{
            let request = NSMutableURLRequest(url: url)
            request.httpMethod = method
            self.wkWebView.load(request as URLRequest)
        }
    }
    
    @objc func toDerRegisterPortal(){
        let vc = DERRegisterPortalViewController()
        
        self.navigationController?.pushViewController(vc, animated: true)
    }
    override func backToPre() {
        //WKWebView中内部返回
        if self.wkWebView.canGoBack {
            
            if !self.withoutNetworkView.isHidden{
                _ = self.navigationController?.popViewController(animated: false)
            }else{
                if let url = self.currentURL{
                    if url.absoluteString.lowercased().contains("derr/installation_details"){//如果是home页面（DER Register页面或者Access Job）直接返回
                        _ = self.navigationController?.popViewController(animated: false)
                    }else if url.absoluteString.lowercased().contains("edit"){//从编辑页面返回时，调用js方法（提示是否保存编辑过的信息）
                        self.wkWebView.evaluateJavaScript("Web_DERChanged()") { (result, err) in
                            if let _ = err {//出错表示没有此方法，直接返回
                                self.wkWebView.goBack()
                            }else if let editFlag = result as? Bool ,editFlag{
                                self.showEditAlertVC()
                            }
                        }
                    }else{
                        self.wkWebView.goBack()
                    }
                }else {
                   self.wkWebView.goBack()
                }
                
            }
            
        }else{
            _ = self.navigationController?.popViewController(animated: false)
        }
    }
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "estimatedProgress" {
            self.progBar.alpha = 1.0
//            print(wkWebView.estimatedProgress)
            progBar.setProgress(Float(wkWebView.estimatedProgress), animated: true)
            //Max value of process bar is 1.0
            if(self.wkWebView.estimatedProgress >= 1.0) {
                UIView.animate(withDuration: 0.3, delay: 0.1, options: UIView.AnimationOptions.curveEaseInOut, animations: { () -> Void in
                    self.progBar.alpha = 0.0
                }, completion: { (finished:Bool) -> Void in
                    self.progBar.progress = 0.0
                })
            }
        }else if keyPath == "title" {
            if object as? WKWebView == self.wkWebView {
                self.title = self.wkWebView.title ?? ""
            }
        }else if keyPath == "URL"{
            //DER Register submit时使用AJAX请求，WXWebView代理方法拦截不到，只能监听URL的变化
            if let url = self.wkWebView.url, url.absoluteString.contains("derr/installation_details") && url.absoluteString.contains("submitted"){
                if Connectivity.isConnectedToInternet {
                    print(url.absoluteString)
                }else{
                    self.showWithoutInternetBackView()
                }
            }
        }
    }
    func showEditAlertVC(){
        Tool().showAlertViewWithTwoBtns(message: "Changes will be lost.\nDo you wish to continue?",cancelStr: R.string.localizable.cancel(), confirmStr: R.string.localizable.oK(),noClosure: nil) {
            //如果是返回到Home页，就重新加载页面，防止编辑页面前Submit信息是红色错误提示信息的存在
            if let url = self.currentURL,let _ = self.homeURL, url.absoluteString.contains("edit") {
                self.wkWebView.load(URLRequest(url: self.homeURL!))
            }else{
                self.wkWebView.goBack()
            }
        }
    }
    override func viewWillAppear(_ animated: Bool) {
        self.tabBarController?.tabBar.isHidden = true
        self.navigationController?.setNavigationBarHidden(false, animated: false)
        if let _ = self.wkWebView{
            // addScriptMessageHandler 很容易导致循环引用
            // 控制器 强引用了WKWebView,WKWebView copy(强引用了）configuration， configuration copy （强引用了）userContentController
            // userContentController 强引用了 self （控制器）
            self.wkWebView.configuration.userContentController.add(self, name: "DERSubmit")//和Web约定的参数
            self.wkWebView.configuration.userContentController.add(self, name: "DERCancel")//和Web约定的参数
            self.wkWebView.configuration.userContentController.add(self, name: "DERChanged")//和Web约定的参数
        }
    }
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        if let _ = self.wkWebView{
            self.wkWebView.configuration.userContentController.removeScriptMessageHandler(forName: "DERSubmit")
            self.wkWebView.configuration.userContentController.removeScriptMessageHandler(forName: "DERCancel")
            self.wkWebView.configuration.userContentController.removeScriptMessageHandler(forName: "DERChanged")
        }
        
    }
    deinit {
        if self.isViewDidLoad {
            self.wkWebView.removeObserver(self, forKeyPath: "title")
            self.wkWebView.removeObserver(self, forKeyPath: "estimatedProgress")
            self.wkWebView.removeObserver(self, forKeyPath: "URL")
        }
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        DebugLog("\(self) didReceiveMemoryWarning")
    }
}
extension DERRegisterViewController: WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler {
    
    //WKUIDelegate:create new webview when click Link in WKWebView
    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView?{
        if !(navigationAction.targetFrame?.isMainFrame != nil) {
            self.wkWebView.load(navigationAction.request)
        }
        return nil
    }
    //当Web视图开始接收Web内容时调用
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        self.showWebView()
    }
    //页面加载完毕时调用
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
//        print("Web视图加载完毕")
    }
    //此方法中拦截URL修改header参数重新load请求会引起编辑device save后跳转不到der register页面的问题
    //此代理方法必须实现，否则假网络时不会调用didFailProvisionalNavigation
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        
        if let url = navigationAction.request.url{
            //编辑页面的cancel使用a标签做的，不管
            if url.absoluteString.contains("javascipt:") {
                decisionHandler(WKNavigationActionPolicy.cancel)
                return
            }
            //Edit device 或ac connection时，加上iOS类型。如果去掉edit的判断
            if navigationAction.request.httpMethod == "GET" && url.absoluteString.contains("edit"){
                let mutableRequest = NSMutableURLRequest(url: url)
                let headerFields = navigationAction.request.allHTTPHeaderFields
                if headerFields != nil , let _ = headerFields!["X-API-MOBILE-TYPE"]{
                    //X-API-MOBILE-TYPE参数存在就不做不处理
                }else{//对于没有X-API-MOBILE-TYPE的链接，手动加上，用户H5中用iOS判断给移动端发post msg
                    mutableRequest.allHTTPHeaderFields = headerFields
                    mutableRequest.setValue("iOS", forHTTPHeaderField: "X-API-MOBILE-TYPE")
                    //
                    self.wkWebView.load(mutableRequest as URLRequest)
                    decisionHandler(WKNavigationActionPolicy.cancel)
                    return
                }
            }
            self.currentURL = url
            self.currentMethod = navigationAction.request.httpMethod
        }
        //在发送请求之前，决定是否跳转
        decisionHandler(WKNavigationActionPolicy.allow)
    }
    //此方法中拦截URL修改header参数重新load请求会引起编辑device save后跳转不到der register页面的问题
    @available(iOS 13.0, *)
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, preferences: WKWebpagePreferences, decisionHandler: @escaping (WKNavigationActionPolicy, WKWebpagePreferences) -> Void) {
        if let url = navigationAction.request.url  {
            if url.absoluteString.contains("javascipt:") {
                decisionHandler(WKNavigationActionPolicy.cancel, preferences)
                return
            }
            //Edit device 或ac connection时，加上iOS hearder参数类型，
            if navigationAction.request.httpMethod == "GET" && url.absoluteString.contains("edit") {
                
                let mutableRequest = NSMutableURLRequest(url: url)
                let headerFields = navigationAction.request.allHTTPHeaderFields
                if headerFields != nil , let _ = headerFields!["X-API-MOBILE-TYPE"]{
                    //X-API-MOBILE-TYPE参数存在就不做不处理
                }else{//对于没有X-API-MOBILE-TYPE的链接，手动加上，用户H5中用iOS判断给移动端发post msg
                    mutableRequest.allHTTPHeaderFields = headerFields
                    mutableRequest.setValue("iOS", forHTTPHeaderField: "X-API-MOBILE-TYPE")

                    //在发送请求之前，决定是否跳转
                    self.wkWebView.load(mutableRequest as URLRequest)
                    decisionHandler(WKNavigationActionPolicy.cancel, preferences)
                    return
                }
            }
            self.currentURL = url
            self.currentMethod = navigationAction.request.httpMethod
        }
        //在发送请求之前，决定是否跳转
        decisionHandler(WKNavigationActionPolicy.allow, preferences)
    }
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        
        decisionHandler(WKNavigationResponsePolicy.allow)
    }
    //此方法必须实现，否则服务器的重定向请求会失败
    func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
//        print("重定向URL：" + webView.url!.absoluteString)
    }
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
//        print("Web视图加载失败2")
    }
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
//        let urlError = error as NSError
//        print(urlError.code)
//        print(urlError.localizedDescription)
//        if urlError.code == -1004 || urlError.code == -1009 {//-1004:无法连接到主机;-1009：The Internet connection appears to be offline.
//            self.showWithoutInternetBackView()
//        }else if urlError.code == -1001 {//请求超时
//            self.showTimeOutBackView()
//        }
        self.showWithoutInternetBackView()
   }
    
   func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        //接收到cancel或submit信息，直接返回到上一级
        if let msg = message.body as? String {
            if msg.contains("DERSubmit") || msg.contains("DERCancel") {
                self.navigationController?.popViewController(animated: false)
            }else if msg.contains("DERChanged") {
                self.showEditAlertVC()
            }
            
        }
    }
}
